package com.ledi.guns.modular.ledipay.service.impl;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import lombok.extern.slf4j.Slf4j;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.ledi.guns.common.exception.AppCheckException;
import com.ledi.guns.common.exception.BussinessException;
import com.ledi.guns.common.persistence.dao.BillClassMapMapper;
import com.ledi.guns.common.persistence.dao.BillDetailMapper;
import com.ledi.guns.common.persistence.dao.BillItemMapMapper;
import com.ledi.guns.common.persistence.dao.BillItemMapper;
import com.ledi.guns.common.persistence.dao.BillMapper;
import com.ledi.guns.common.persistence.dao.BillWeixinMapper;
import com.ledi.guns.common.persistence.dao.ClassInfoMapper;
import com.ledi.guns.common.persistence.dao.DeptMapper;
import com.ledi.guns.common.persistence.dao.GradeMapper;
import com.ledi.guns.common.persistence.dao.RoleMapper;
import com.ledi.guns.common.persistence.dao.SchoolInfoMapper;
import com.ledi.guns.common.persistence.dao.SchoolPayItemMapper;
import com.ledi.guns.common.persistence.dao.StudentMapper;
import com.ledi.guns.common.persistence.dao.TeacherClassMapMapper;
import com.ledi.guns.common.persistence.dao.UserMapper;
import com.ledi.guns.common.persistence.model.Bill;
import com.ledi.guns.common.persistence.model.BillClassMap;
import com.ledi.guns.common.persistence.model.BillDetail;
import com.ledi.guns.common.persistence.model.BillItemMap;
import com.ledi.guns.common.persistence.model.BillWeixin;
import com.ledi.guns.common.persistence.model.ClassInfo;
import com.ledi.guns.common.persistence.model.Grade;
import com.ledi.guns.common.persistence.model.Role;
import com.ledi.guns.common.persistence.model.SchoolInfo;
import com.ledi.guns.common.persistence.model.SchoolPayItem;
import com.ledi.guns.common.persistence.model.Student;
import com.ledi.guns.common.persistence.model.TeacherClassMap;
import com.ledi.guns.common.persistence.model.User;
import com.ledi.guns.common.persistence.model.vo.BillClassSchoolItemVo;
import com.ledi.guns.common.persistence.model.vo.BillDetailVo;
import com.ledi.guns.common.persistence.model.vo.BillVo;
import com.ledi.guns.common.persistence.model.vo.ClassInfoVo;
import com.ledi.guns.common.persistence.model.vo.CountTotal;
import com.ledi.guns.common.persistence.model.vo.OnlineVo;
import com.ledi.guns.common.persistence.model.vo.UserVo;
import com.ledi.guns.core.redis.KeyValueDAO;
import com.ledi.guns.core.shiro.ShiroKit;
import com.ledi.guns.core.shiro.ShiroUser;
import com.ledi.guns.core.util.DateUtil;
import com.ledi.guns.core.util.IdGenerator;
import com.ledi.guns.core.util.PayUtil;
import com.ledi.guns.core.util.StringUtil;
import com.ledi.guns.core.util.SystemConstans;
import com.ledi.guns.modular.ledipay.controller.req.bill.AddSchoolUser;
import com.ledi.guns.modular.ledipay.controller.req.bill.DownloadBillDetailExcel;
import com.ledi.guns.modular.ledipay.controller.req.bill.Face2FaceBill;
import com.ledi.guns.modular.ledipay.controller.req.bill.FaceQueryBillInfo;
import com.ledi.guns.modular.ledipay.controller.req.bill.ImportBillDetaile;
import com.ledi.guns.modular.ledipay.controller.req.bill.ImportBillDetaileFile;
import com.ledi.guns.modular.ledipay.controller.req.bill.OfflinePayment;
import com.ledi.guns.modular.ledipay.controller.req.bill.QueryBillDetaile;
import com.ledi.guns.modular.ledipay.controller.req.bill.QueryBillInfo;
import com.ledi.guns.modular.ledipay.controller.req.bill.QueryCountTotal;
import com.ledi.guns.modular.ledipay.controller.req.bill.QueryUserInfo;
import com.ledi.guns.modular.ledipay.service.IBillService;

/**
 * 账单Service
 *
 * @author fengshuonan
 * @Date 2017-11-29 11:02:55
 */
@Service
@Slf4j
public class BillServiceImpl implements IBillService {

	@Autowired
	private UserMapper userMapper;
	@Autowired
	private ClassInfoMapper classInfoMapper;
	@Autowired
	private BillDetailMapper billDetailMapper;
	@Autowired
	private BillMapper billMapper;
	@Autowired
	private BillItemMapper billItemMapper;
	@Autowired
	private RoleMapper roleMapper;
	@Autowired
	private DeptMapper deptMapper;
	@Autowired
	private TeacherClassMapMapper teacherClassMapMapper;
	@Autowired
	private BillWeixinMapper billWeixinMapper;
	@Autowired
	private SchoolInfoMapper schoolInfoMapper;
	@Autowired
	private SchoolPayItemMapper schoolPayItemMapper;
	@Autowired
	private BillClassMapMapper billClassMapMapper;
	@Autowired
	private BillItemMapMapper billItemMapMapper;

	@Value("${import.file.address}")
	private String importFileAddress;

	@Value("${import.bill.name.length}")
	private Integer importBillNameLength;
	@Value("${import.content.name.length}")
	private Integer importContentNameLength;
	@Autowired
	private KeyValueDAO keyValueDAO;
	@Autowired
	private StudentMapper studentMapper;
	@Autowired
	private GradeMapper gradeMapper;

	@SuppressWarnings("resource")
	@Override
	@Transactional
	public ImportBillDetaileFile newSendBillDetaile(ImportBillDetaile importBillDetaile) {

		ShiroUser currentUser = ShiroKit.getUser();
		Integer creatorId = currentUser.getId();
		User user = userMapper.selectById(creatorId);
		userIsDelete(user, "newSendBillDetaile");
		Long schoolId = user.getSchoolId();

		if (schoolId == null) {
			throw new AppCheckException("school.user.noSchool.code", "school.user.noSchool.message");
		}
		String role = user.getRoleid();
		ImportBillDetaileFile importBillDetaileFile = null;
		// 应缴金额
		File file = null;
		InputStream is = null;

		// 校验文件格式
		String fileType = importBillDetaile.getBillDetaileUrl().substring(
				importBillDetaile.getBillDetaileUrl().lastIndexOf(".") + 1,
				importBillDetaile.getBillDetaileUrl().length());
		fileType = fileType.toLowerCase();

		// 校验截止时间
		if (new Date().after(importBillDetaile.getBillEndTime())) {
			throw new AppCheckException("school.zhangdan.billEndTime.code", "school.zhangdan.billEndTime.message");
		}

		// 校验名称
		if (importBillDetaile.getBillName().length() > importBillNameLength) {
			throw new AppCheckException("school.zhangdan.name.code", "school.zhangdan.name.message",
					new Object[] { "账单名称", importBillNameLength });
		}

		try {
			try {
				// 获取文档，报错后捕捉
				file = new File(importFileAddress + importBillDetaile.getBillDetaileUrl());
				is = new FileInputStream(file);
			} catch (Exception e) {
				e.printStackTrace();
				throw new AppCheckException("school.zhangdan.import.file.code", "school.zhangdan.import.file.message",
						"");
			}
			Workbook workbook = null;
			if ("xls".equals(fileType)) {
				try {
					workbook = new HSSFWorkbook(is);
				} catch (Exception e) {
					throw new AppCheckException("school.zhangdan.billFormat.code", "school.zhangdan.billFormat.message",
							"");
				}
			} else if ("xlsx".equals(fileType)) {
				try {
					workbook = new XSSFWorkbook(is);
				} catch (Exception e) {
					throw new AppCheckException("school.zhangdan.billFormat.code", "school.zhangdan.billFormat.message");
				}
			} else {
				throw new AppCheckException("school.zhangdan.billFormat.code", "school.zhangdan.billFormat.message");
			}

			// 获取Excel文档中的第一个表单
			Sheet sheet = workbook.getSheetAt(0);
			if (importBillDetaile.getBillEndTime() != null) {
				importBillDetaile.getBillEndTime().setHours(23);
				importBillDetaile.getBillEndTime().setMinutes(59);
				importBillDetaile.getBillEndTime().setSeconds(59);
			}

			List<BillDetail> billDetailList = new ArrayList<BillDetail>();
			List<ClassInfo> classInfoList = new ArrayList<ClassInfo>();
			// 收费项目
			List<Long> schoolPayItems = new ArrayList<Long>();
			// 循环读出缴费项目名称
			List<String> itemList = new ArrayList<String>();
			for (int i = 5; true; i++) {
				if (sheet.getRow(2) != null) {
					Cell cell = sheet.getRow(2).getCell(i);
					if (cell != null) {
						String itemName = cellConversionString(cell);
						if (!StringUtil.isBlank(itemName)) {
							itemList.add(itemName.substring(0, itemName.lastIndexOf("-") != -1 ? itemName.lastIndexOf("-") : itemName.length()));
						}

					} else {
						break;
					}
				} else {
					break;
				}
			}

			if (itemList.size() == 0) {
				throw new AppCheckException("school.zhangdan.send.file.code",
						"school.zhangdan.send.file.message",
						new Object[] { 3, 6, "缴费项目不能少于一个" });
			}

			// 循环行
			for (Row row : sheet) {
				// 如果当前行的行号（从0开始）未达到2（第三行）则从新循环
				if (row.getRowNum() < 3) {
					continue;
				}
				// 创建实体类
				BillDetail billDetail = new BillDetail();
				ClassInfo classInfo = new ClassInfo();
				// 年级 班级序号 班级别名 学生姓名 家长手机号 保育教育费 餐费 餐费退款-退款 服装费-可选
				// 取出年级名称
				Cell cell0 = row.getCell(0);
				Grade grade = null;
				if (cell0 != null) {
					String gradeName = cellConversionString(cell0);
					if (StringUtil.isNotBlank(gradeName)) {
						if (gradeName.length() > importContentNameLength) {
							throw new AppCheckException("school.zhangdan.send.file.code",
									"school.zhangdan.send.file.message",
									new Object[] { row.getRowNum() + 1, 1, "年级名称字数不能超过" + importBillNameLength });
						}

						Grade columnMap = new Grade();
						columnMap.setName(gradeName);
						columnMap.setIsDelete(SystemConstans.NO);
						grade = gradeMapper.selectOne(columnMap);
						if (grade == null) {
							throw new AppCheckException("school.zhangdan.send.file.code",
									"school.zhangdan.send.file.message",
									new Object[] { row.getRowNum() + 1, 1, "年级名称不存在" });
						}
					} else {
						break;
					}
				}
				// 取出班级序号
				Cell cell1 = row.getCell(1);
				Integer orderNum = null;
				if (cell1 != null) {
					String order_num = cellConversionString(cell1);
					if (StringUtil.isNotBlank(order_num)) {
						orderNum = Integer.parseInt(order_num);
						if (orderNum > 100) {
							throw new AppCheckException("school.zhangdan.send.file.code",
									"school.zhangdan.send.file.message",
									new Object[] { row.getRowNum() + 1, 1, "班级序号不能超过100" });
						}
					}
				}
				// 取出班级别名
				Cell cell2 = row.getCell(2);
				if (cell2 != null) {
					String className = cellConversionString(cell2);
					if (StringUtil.isNotBlank(className)) {
						if (className.length() > importContentNameLength) {
							throw new AppCheckException("school.zhangdan.send.file.code",
									"school.zhangdan.send.file.message",
									new Object[] { row.getRowNum() + 1, 1, "班级名称字数不能超过" + importBillNameLength });
						}
						ClassInfo columnMap = new ClassInfo();
						columnMap.setName(className);
						columnMap.setIsDelete(SystemConstans.NO);
						columnMap.setOrderNum(orderNum);
						columnMap.setSchoolId(schoolId);
						ClassInfo selectByMap = classInfoMapper.selectOne(columnMap);
						if (selectByMap == null) {
							throw new AppCheckException("school.zhangdan.send.file.code",
									"school.zhangdan.send.file.message",
									new Object[] { row.getRowNum() + 1, 1, "班级不存在" });
						}
						BeanUtils.copyProperties(selectByMap, classInfo);
					} else {
						ClassInfo columnMap = new ClassInfo();
						columnMap.setGradeId(grade.getId());
						columnMap.setIsDelete(SystemConstans.NO);
						columnMap.setOrderNum(orderNum);
						columnMap.setSchoolId(schoolId);
						ClassInfo selectByMap = classInfoMapper.selectOne(columnMap);
						if (selectByMap == null) {
							throw new AppCheckException("school.zhangdan.send.file.code",
									"school.zhangdan.send.file.message",
									new Object[] { row.getRowNum() + 1, 1, "班级不存在" });
						}
						BeanUtils.copyProperties(selectByMap, classInfo);
					}
				}
				// 学生姓名
				Cell cell3 = row.getCell(3);
				String studentName = null;
				if (cell3 != null) {
					studentName = cellConversionString(cell3);
					if (StringUtil.isNotBlank(studentName)) {
						if (studentName.length() > importContentNameLength) {
							throw new AppCheckException("school.zhangdan.send.file.code",
									"school.zhangdan.send.file.message",
									new Object[] { row.getRowNum() + 1, 1, "学生名称字数不能超过" + importBillNameLength });
						}
					}
				}
				// 家长手机号
				Cell cell4 = row.getCell(4);
				if (cell4 != null) {
					String parentMobile = cellConversionString(cell4);
					if (StringUtil.isNotBlank(parentMobile)) {
						if (parentMobile.length() > 11) {
							throw new AppCheckException("school.zhangdan.send.file.code",
									"school.zhangdan.send.file.message",
									new Object[] { row.getRowNum() + 1, 1, "家长手机号位数不能超过" + 11 });
						}
						Student columnMap = new Student();
						columnMap.setParentMobile(parentMobile);
						columnMap.setIsDelete(SystemConstans.NO);
						columnMap.setSchoolId(schoolId);
						columnMap.setName(studentName);
						columnMap.setGradeId(grade.getId());
						Student selectByMap = studentMapper.selectOne(columnMap);
						if (selectByMap == null) {
							throw new AppCheckException("school.zhangdan.send.file.code",
									"school.zhangdan.send.file.message",
									new Object[] { row.getRowNum() + 1, 1, "家长手机号或者学生名称不存在" });
						}
						billDetail.setStudentName(studentName);
						billDetail.setParentMobile(parentMobile);
					}
				}

				// 缴费项目
				// 如果都是空的情况下就停止循环
				if (billDetail.getStudentName() == null) {
					throw new AppCheckException("school.zhangdan.send.file.code",
							"school.zhangdan.send.file.message",
							new Object[] { row.getRowNum() + 1, 4, "学生姓名输入错误" });
				}
				if (billDetail.getParentMobile() == null) {
					throw new AppCheckException("school.zhangdan.send.file.code",
							"school.zhangdan.send.file.message",
							new Object[] { row.getRowNum() + 1, 5, "家长的手机号输入错误" });

				}

				for (int i = 5; i <= itemList.size() + 4; i++) {
					BigDecimal be = null;
					// 获取项目金额
					Cell cellMoner = row.getCell(i);
					if (cellMoner != null) {
						String itemMonerS = "";
						double itemMoner = 0;
						try {
							// 如果excel金额是数值
							itemMoner = cellMoner.getNumericCellValue();
							if (itemMoner == 0) {
								be = new BigDecimal(0);
							}
						} catch (Exception e) {
							// 如果excel金额是文本
							itemMonerS = cellMoner.getStringCellValue();
							if ("".equals(itemMonerS)) {
								be = new BigDecimal(0);
							}
						}
						try {
							if (!"".equals(itemMonerS)) {
								be = new BigDecimal(itemMonerS);
							} else if (itemMoner != 0) {
								be = new BigDecimal(itemMoner);
							}
						} catch (Exception e) {
							throw new AppCheckException("school.zhangdan.send.file.code",
									"school.zhangdan.send.file.message",
									new Object[] { row.getRowNum() + 1, i + 1, "金额输入错误" });
						}
						if (be.compareTo(new BigDecimal("0")) <= 0) {
							throw new AppCheckException("school.zhangdan.send.file.code",
									"school.zhangdan.send.file.message",
									new Object[] { row.getRowNum() + 1, i + 1, "金额输入错误" });
						}
						if (be.compareTo(new BigDecimal("0")) == 0) {
							continue;
						}
						String itemName = "";
						try {
							itemName = itemList.get(i - 5);
						} catch (Exception e) {
							throw new AppCheckException("school.zhangdan.send.file.code",
									"school.zhangdan.send.file.message",
									new Object[] { row.getRowNum() + 1, i + 1, "没有支付项目" });
						}
						if (be.compareTo(new BigDecimal(99999999)) > 0) {
							throw new AppCheckException("school.zhangdan.send.file.code",
									"school.zhangdan.send.file.message",
									new Object[] { row.getRowNum() + 1, i + 1, "金额不能大于99999999" });
						}

						Map<String, Object> itemQuery = new HashMap<String, Object>();
						itemQuery.put("school_id", schoolId);
						itemQuery.put("name", itemName);
						itemQuery.put("money", be.doubleValue());
						itemQuery.put("is_delete", SystemConstans.NO);
						List<SchoolPayItem> payItem = schoolPayItemMapper.selectByMap(itemQuery);
						if (CollectionUtils.isEmpty(payItem)) {
							throw new AppCheckException("school.zhangdan.send.file.code",
									"school.zhangdan.send.file.message",
									new Object[] { row.getRowNum() + 1, i + 1, "该缴费项和金额未添加至学校收费项" });
						}
						if (row.getRowNum() == 3) {
							schoolPayItems.add(payItem.get(0).getId());
						}
					}
				}
				billDetailList.add(billDetail);
				classInfoList.add(classInfo);

			}
			// 插入账单表，生成ID
			Bill bill = new Bill();
			bill.setName(importBillDetaile.getBillName());
			bill.setBillEndTime(importBillDetaile.getBillEndTime());
			bill.setIsDelete(0);
			bill.setCreateTime(new Date());
			bill.setCreatorId(Long.valueOf(creatorId));
			bill.setCreatorRole(role);
			bill.setSchoolId(schoolId);
			bill.setBillType(SystemConstans.YES);
			bill.setBillNumber(IdGenerator.getId());
			Integer insertBill = billMapper.insert(bill);
			if (insertBill < 1) {
				throw new AppCheckException("school.zhangdan.import.code", "school.zhangdan.import.message");
			}
			if (billDetailList.size() != 0 && classInfoList.size() != 0 && schoolPayItems.size() != 0
					&& billDetailList.size() == classInfoList.size()) {
				if (billDetailList.size() > 1000) {
					throw new AppCheckException("school.zhangdan.import.number.code",
							"school.zhangdan.import.number.message",
							"1000");
				}
				insertBillDetailList(bill, role, creatorId, schoolId, billDetailList, classInfoList,
						schoolPayItems);

			} else if (billDetailList.size() == 0 && classInfoList.size() == 0 && schoolPayItems.size() == 0) {
				// 如果导入内容为空
				throw new AppCheckException("school.zhangdan.excel.number.code", "school.zhangdan.excel.number.message",
						"");
			} else {
				// 未知错误
				throw new AppCheckException("school.zhangdan.import.code", "school.zhangdan.import.message");
			}
			importBillDetaileFile = new ImportBillDetaileFile();
			importBillDetaileFile.setId(bill.getId());
			importBillDetaileFile.setStudentNum(billDetailList.size());
			bill.setStudentNum(billDetailList.size());
			Integer updateBill = billMapper.updateById(bill);
			if (updateBill < 1) {
				throw new AppCheckException("school.zhangdan.import.code", "school.zhangdan.import.message");
			}
		} catch (Exception e) {
			if (e instanceof BussinessException) {
				throw (BussinessException) e;
			} else if (e instanceof AppCheckException) {
				throw (AppCheckException) e;
			} else {
				throw new AppCheckException("school.zhangdan.import.code", "school.zhangdan.import.message");
			}
		} finally {
			try {
				if (is != null) {
					is.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
				throw new AppCheckException("school.zhangdan.import.code", "school.zhangdan.import.message");
			}
			if (file.isFile()) {// 如果是文件
				file.delete();
			}
		}
		return importBillDetaileFile;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void downloadBillDetaile(
			HttpServletRequest request, HttpServletResponse response) {

		ShiroUser currentUser = ShiroKit.getUser();
		User user = userMapper.selectById(currentUser.getId());
		if (!user.getStatus().equals(SystemConstans.YES)) {
			throw new AppCheckException("school.user.notActive.code", "school.user.notActive.message");
		}
		Long schoolId = user.getSchoolId();
		if (schoolId == null) {
			throw new AppCheckException("school.user.noSchool.code", "school.user.noSchool.message");
		}
		DownloadBillDetailExcel downloadBillDetailExcel = new DownloadBillDetailExcel();
		String billId = request.getParameter("billId");
		String billDetailIds = request.getParameter("billDetailIds");
		String startTime = request.getParameter("startTime");
		String endTime = request.getParameter("endTime");
		String sendStatus = request.getParameter("sendStatus");
		String studentName = request.getParameter("studentName");
		String parentMobile = request.getParameter("parentMobile");
		String classId = request.getParameter("classId");
		String payStatus = request.getParameter("payStatus");
		String billDetailId = request.getParameter("billDetailId");

		if (StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime)) {
			downloadBillDetailExcel.setStartTime(DateUtil.parseTime(startTime));
			downloadBillDetailExcel.setEndTime(DateUtil.parseTime(endTime));
		}
		downloadBillDetailExcel.setBillId(billId == null || "".equals(billId) ? null : Long.parseLong(billId));
		downloadBillDetailExcel.setBillDetailIds(billDetailIds);
		List<Long> ids = null;
		Map<String, Object> map = new HashMap<String, Object>();
		if (StringUtil.isNotBlank(downloadBillDetailExcel.getBillDetailIds())) {
			String[] sIds = downloadBillDetailExcel.getBillDetailIds().split(",");
			ids = new ArrayList<Long>();
			for (String id : sIds) {
				ids.add(Long.parseLong(id));
			}
			map.put("ids", ids);
		} else {
			Date start, end;
			extracted(downloadBillDetailExcel);
			Date startDate = downloadBillDetailExcel.getStartTime();
			Date endDate = downloadBillDetailExcel.getEndTime();
			if (startDate == null || endDate == null) {
				end = new Date();
				start = DateUtil.addMonthsToDate(end, -6);
				List<Date> formateDate = DateUtil.formateDate(start, end);
				start = formateDate.get(0);
				end = formateDate.get(1);
				startDate = start;
				endDate = end;
			} else {
				Date a = DateUtil.addMonthsToDate(startDate, 6);
				if (a.before(endDate)) {
					throw new AppCheckException("school.bill.export.fail.code", "school.bill.export.fail.message");
				}
			}
			map.put("startTime", startDate);
			map.put("endTime", endDate);
		}
		if (downloadBillDetailExcel.getBillId() != null) {
			map.put("billId", downloadBillDetailExcel.getBillId());
		}
		map.put("schoolId", schoolId);

		if (!ShiroKit.isDirector()) {
			map.put("userId", user.getId());
		}
		List<Integer> sendStatusList = null;
		if (StringUtil.isNotBlank(sendStatus)) {
			sendStatusList = new ArrayList<Integer>();
			if ("0".equals(sendStatus)) {
				sendStatusList.add(-1);
				sendStatusList.add(3);
			} else if ("1".equals(sendStatus)) {
				sendStatusList.add(1);
				sendStatusList.add(2);
			} else if ("2".equals(sendStatus)) {
				sendStatusList.add(5);
				sendStatusList.add(6);
			} else if ("3".equals(sendStatus)) {
				sendStatusList.add(4);
			} else if ("4".equals(sendStatus)) {
				sendStatusList.add(5);
				sendStatusList.add(6);

				map.put("payWay", SystemConstans.PAY_WAY_ALI);
			} else if ("5".equals(sendStatus)) {
				sendStatusList.add(5);
				sendStatusList.add(6);
				map.put("payWay", SystemConstans.PAY_WAY_WEIXIN);
			}
			map.put("list", sendStatusList);
		}

		if (StringUtils.isNotBlank(payStatus)) {
			switch (payStatus) {
				case "0":
					map.put("payWay", SystemConstans.PAY_WAY_ALI);
					break;
				case "1":
					map.put("payWay", SystemConstans.PAY_WAY_WEIXIN);
					break;
				case "2":
					map.put("payWay", SystemConstans.PAY_WAY_CASH);
					break;
				case "3":
					map.put("payWay", SystemConstans.PAY_WAY_GIRO);
					break;
				case "4":
					map.put("payWay", SystemConstans.PAY_WAY_OTHER);
					break;
				default:
					break;
			}
		}
		if (StringUtils.isNotBlank(studentName)) {
			map.put("studentName", studentName);
		}
		if (StringUtils.isNotBlank(parentMobile)) {
			map.put("parentMobile", parentMobile);
		}
		if (StringUtils.isNotBlank(classId)) {
			map.put("classId", classId);
		}

		if (StringUtils.isNotBlank(billDetailId)) {
			map.put("billDetailId", billDetailId);
		}
		List<BillDetailVo> billDetailVoList = billMapper.selectBillDetaileById(map);
		if (billDetailVoList == null || billDetailVoList.size() < 1) {
			throw new AppCheckException("school.zhangdan.noteixt.code", "school.zhangdan.noteixt.message");
		}
		if (downloadBillDetailExcel.getBillId() == null) {
			for (BillDetailVo billDetailVo : billDetailVoList) {
				if (billDetailVo.getBillId().equals(-1L)) {
					if (SystemConstans.PAY_WAY_WEIXIN.equals(billDetailVo.getPayWay())) {
						BillWeixin billWeixin = new BillWeixin();
						billWeixin.setBillDetailId(billDetailVo.getBillDetailId());
						billWeixin = billWeixinMapper.selectOne(billWeixin);
						if (billWeixin != null) {
							billDetailVo.setAlipayOrderNo(billWeixin.getWeixinTransactionId());
							billDetailVo.setPayTime(billWeixin.getPayTime());
						}
					}
				}
			}
		}
		HSSFWorkbook workbook = new HSSFWorkbook();// 创建一个Excel文件
		HSSFSheet sheet = workbook.createSheet();// 创建一个Excel的Sheet
		sheet.createFreezePane(0, 1, 0, 1);
		// sheet.createFreezePane(0, 1);// 冻结
		// 设置列宽
		sheet.setColumnWidth(0, 4500);
		sheet.setColumnWidth(1, 3500);
		sheet.setColumnWidth(2, 4500);
		sheet.setColumnWidth(3, 6500);
		sheet.setColumnWidth(4, 3500);
		sheet.setColumnWidth(5, 6500);
		sheet.setColumnWidth(6, 8500);
		// sheet.setColumnWidth(7, 6500);
		sheet.setColumnWidth(7, 6500);
		sheet.setColumnWidth(8, 6500);
		sheet.setColumnWidth(9, 3500);
		sheet.setColumnWidth(10, 6500);
		// Sheet样式
		HSSFCellStyle sheetStyle = workbook.createCellStyle();
		// 设置字体
		HSSFFont headfont = workbook.createFont();
		headfont.setFontName("黑体");
		headfont.setFontHeightInPoints((short) 22);// 字体大小
		headfont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);// 加粗
		// 另一个样式
		HSSFCellStyle headstyle = workbook.createCellStyle();
		headstyle.setFont(headfont);
		headstyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 左右居中
		headstyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 上下居中
		headstyle.setLocked(true);
		headstyle.setWrapText(true);// 自动换行
		// 另一个字体样式
		HSSFFont columnHeadFont = workbook.createFont();
		columnHeadFont.setFontName("宋体");
		columnHeadFont.setFontHeightInPoints((short) 10);
		columnHeadFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
		// 列头的样式
		HSSFCellStyle columnHeadStyle = workbook.createCellStyle();
		columnHeadStyle.setFont(columnHeadFont);
		columnHeadStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 左右居中
		columnHeadStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 上下居中
		columnHeadStyle.setLocked(true);
		columnHeadStyle.setWrapText(true);
		columnHeadStyle.setLeftBorderColor(HSSFColor.BLACK.index);// 左边框的颜色
		columnHeadStyle.setBorderLeft((short) 1);// 边框的大小
		columnHeadStyle.setRightBorderColor(HSSFColor.BLACK.index);// 右边框的颜色
		columnHeadStyle.setBorderRight((short) 1);// 边框的大小
		columnHeadStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN); // 设置单元格的边框为粗体
		columnHeadStyle.setBottomBorderColor(HSSFColor.BLACK.index); // 设置单元格的边框颜色
		// 设置单元格的背景颜色（单元格的样式会覆盖列或行的样式）
		columnHeadStyle.setFillForegroundColor(HSSFColor.WHITE.index);
		HSSFFont font = workbook.createFont();
		font.setFontName("宋体");
		font.setFontHeightInPoints((short) 10);
		// 普通单元格样式
		HSSFCellStyle style = workbook.createCellStyle();
		style.setFont(font);
		style.setAlignment(HSSFCellStyle.ALIGN_LEFT);// 左右居中
		style.setVerticalAlignment(HSSFCellStyle.VERTICAL_TOP);// 上下居中
		style.setWrapText(true);
		style.setLeftBorderColor(HSSFColor.BLACK.index);
		style.setBorderLeft((short) 1);
		style.setRightBorderColor(HSSFColor.BLACK.index);
		style.setBorderRight((short) 1);
		style.setBorderBottom(HSSFCellStyle.BORDER_THIN); // 设置单元格的边框为粗体
		style.setBottomBorderColor(HSSFColor.BLACK.index); // 设置单元格的边框颜色．
		style.setFillForegroundColor(HSSFColor.WHITE.index);// 设置单元格的背景颜色．
		// 另一个样式
		HSSFCellStyle centerstyle = workbook.createCellStyle();
		centerstyle.setFont(font);
		centerstyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 左右居中
		centerstyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 上下居中
		// centerstyle.setWrapText(true);
		centerstyle.setLeftBorderColor(HSSFColor.BLACK.index);
		centerstyle.setBorderLeft((short) 1);
		centerstyle.setRightBorderColor(HSSFColor.BLACK.index);
		centerstyle.setBorderRight((short) 1);
		centerstyle.setBorderBottom(HSSFCellStyle.BORDER_THIN); // 设置单元格的边框为粗体
		centerstyle.setBottomBorderColor(HSSFColor.BLACK.index); // 设置单元格的边框颜色．
		centerstyle.setFillForegroundColor(HSSFColor.WHITE.index);// 设置单元格的背景颜色．
		try {
			// 创建第一行
			HSSFRow row2 = sheet.createRow(0);
			row2.setHeight((short) 750);
			HSSFCell cell = row2.createCell(0);
			cell.setCellValue(new HSSFRichTextString("账单编号"));
			cell.setCellStyle(columnHeadStyle);
			cell = row2.createCell(1);
			cell.setCellValue(new HSSFRichTextString("账单名称"));
			cell.setCellStyle(columnHeadStyle);
			cell = row2.createCell(2);
			cell.setCellValue(new HSSFRichTextString("学生姓名"));
			cell.setCellStyle(columnHeadStyle);
			cell = row2.createCell(3);
			cell.setCellValue(new HSSFRichTextString("班级"));
			cell.setCellStyle(columnHeadStyle);
			cell = row2.createCell(4);
			cell.setCellValue(new HSSFRichTextString("家长手机号"));// 前次会议要求\n/新项目的项目概要
			cell.setCellStyle(columnHeadStyle);
			cell = row2.createCell(5);
			cell.setCellValue(new HSSFRichTextString("账单金额（元）"));
			cell.setCellStyle(columnHeadStyle);
			cell = row2.createCell(6);
			cell.setCellValue(new HSSFRichTextString("账单明细（元）"));
			cell.setCellStyle(columnHeadStyle);
			cell = row2.createCell(7);
			cell.setCellValue(new HSSFRichTextString("账单生成日期"));
			cell.setCellStyle(columnHeadStyle);
			cell = row2.createCell(8);
			cell.setCellValue(new HSSFRichTextString("账单状态"));
			cell.setCellStyle(columnHeadStyle);
			cell = row2.createCell(9);
			cell.setCellValue(new HSSFRichTextString("支付方式"));
			cell.setCellStyle(columnHeadStyle);
			cell = row2.createCell(10);
			cell.setCellValue(new HSSFRichTextString("支付时间"));
			cell.setCellStyle(columnHeadStyle);
			cell = row2.createCell(11);
			cell.setCellValue(new HSSFRichTextString("支付编号"));
			cell.setCellStyle(columnHeadStyle);
			cell = row2.createCell(12);
			cell.setCellValue(new HSSFRichTextString("备注"));
			cell.setCellStyle(columnHeadStyle);
			for (int j = 0; j < billDetailVoList.size(); j++) {
				BillDetailVo vo = billDetailVoList.get(j);
				HSSFRow row = sheet.createRow(j + 1);
				// 账单编号
				cell = row.createCell(0);
				cell.setCellValue(new HSSFRichTextString(vo.getBillDetailId()));
				cell.setCellStyle(style);
				// 账单名称
				cell = row.createCell(1);
				cell.setCellValue(new HSSFRichTextString(vo.getBillName()));
				cell.setCellStyle(style);
				// 学生名称
				cell = row.createCell(2);
				cell.setCellValue(new HSSFRichTextString(vo.getStudentName()));
				cell.setCellStyle(style);
				// 班级名称
				cell = row.createCell(3);
				cell.setCellValue(new HSSFRichTextString(vo.getClassName()));
				cell.setCellStyle(style);
				// 家长手机号
				cell = row.createCell(4);
				cell.setCellValue(new HSSFRichTextString(vo.getParentMobile()));
				cell.setCellStyle(style);
				// 账单金额
				cell = row.createCell(5);
				cell.setCellValue(new HSSFRichTextString(vo.getTotalDetail() != null ? vo.getTotalDetail().toString() : ""));
				cell.setCellStyle(style);
				// 缴费详情
				cell = row.createCell(6);
				String payItem = vo.getPayItem();
				if (StringUtils.isNotBlank(payItem)) {
					List<SchoolPayItem> list = JSON.parseArray(payItem, SchoolPayItem.class);
					List<Map<String, Object>> map1 = new ArrayList<Map<String, Object>>();
					for (SchoolPayItem item : list) {
						Map<String, Object> m = new HashMap<String, Object>();
						m.put(item.getName(), item.getMoney());
						map1.add(m);
					}
					payItem = map1.toString().replace("[", "").replace("]", "").replace("{", "").replace("}", "").replace("=", ":");
				}
				cell.setCellValue(new HSSFRichTextString(payItem));
				cell.setCellStyle(style);

				// 生成时间
				cell = row.createCell(7);
				cell.setCellValue(
						new HSSFRichTextString(vo.getCreateTime() == null ? "" : DateUtil.getTime(vo.getCreateTime())));
				cell.setCellStyle(style);
				// 账单状态
				cell = row.createCell(8);
				cell.setCellValue(new HSSFRichTextString(vo.getBillStatusName()));
				cell.setCellStyle(style);
				// 支付方式
				cell = row.createCell(9);
				String payWay = vo.getPayWay();
				switch (payWay) {
					case SystemConstans.PAY_WAY_GIRO:
						payWay = SystemConstans.PAY_WAY_GIRO_ZH;
						break;
					case SystemConstans.PAY_WAY_ALI:
						payWay = SystemConstans.PAY_WAY_ALI_ZH;
						break;
					case SystemConstans.PAY_WAY_WEIXIN:
						payWay = SystemConstans.PAY_WAY_WEIXIN_ZH;
						break;
					case SystemConstans.PAY_WAY_CASH:
						payWay = SystemConstans.PAY_WAY_CASH_ZH;
						break;
					case SystemConstans.PAY_WAY_OTHER:
						payWay = SystemConstans.PAY_WAY_OTHER_ZH;
						break;
					default:
						break;
				}
				cell.setCellValue(new HSSFRichTextString(payWay));
				cell.setCellStyle(style);
				// 支付时间
				cell = row.createCell(10);
				cell.setCellValue(
						new HSSFRichTextString(vo.getPayTime() == null ? "" : DateUtil.getTime(vo.getPayTime())));
				cell.setCellStyle(style);
				// 支付编号
				cell = row.createCell(11);
				cell.setCellValue(
						new HSSFRichTextString(vo.getBillDetailId()));
				cell.setCellStyle(style);
				// 备注
				cell = row.createCell(12);
				cell.setCellValue(new HSSFRichTextString(vo.getComment()));
				cell.setCellStyle(style);
			}

		} catch (Exception e) {
			throw new AppCheckException("school.zhangdan.download.code", "school.zhangdan.download.message");
		}
		String filename = "缴费账单对照表" + DateUtil.getAllTime() + ".xls";
		OutputStream ouputStream = null;
		try {
			ouputStream = response.getOutputStream();
			filename = URLEncoder.encode(filename, "UTF-8");
			// 导出excel
			response.setCharacterEncoding("utf-8");
			response.setContentType("application/vnd.ms-excel");
			response.setHeader("Content-disposition", "attachment;filename=" + filename);
			workbook.write(ouputStream);
		} catch (IOException e) {
			e.printStackTrace();
			throw new AppCheckException("school.zhangdan.download.code", "school.zhangdan.download.message");
		} finally {
			try {
				ouputStream.flush();
			} catch (IOException e) {
				e.printStackTrace();
				throw new AppCheckException("school.zhangdan.download.code", "school.zhangdan.download.message");
			} finally {
				try {
					ouputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
					throw new AppCheckException("school.zhangdan.download.code", "school.zhangdan.download.message");
				}
			}

		}
	}

	@Override
	public Page<BillVo> findBillList(Page<BillVo> page, QueryBillInfo queryBillInfo) {

		ShiroUser currentUser = ShiroKit.getUser();
		User user = userMapper.selectById(currentUser.getId());
		if (1 != user.getStatus()) {
			throw new AppCheckException("school.user.notActive.code", "school.user.notActive.message");
		}
		Long schoolId = user.getSchoolId();
		queryBillInfo.setSchoolId(schoolId);
		extracted(queryBillInfo);

		if (!ShiroKit.isDirector()) {
			Map<String, Object> columnMap = new HashMap<String, Object>();
			columnMap.put("school_id", schoolId);
			columnMap.put("teacher_id", user.getId());
			List<TeacherClassMap> selectByMap = teacherClassMapMapper.selectByMap(columnMap);
			if (CollectionUtils.isNotEmpty(selectByMap)) {
				List<Long> classIds = selectByMap.stream().map(TeacherClassMap::getClassId).collect(Collectors.toList());

				if (CollectionUtils.isNotEmpty(classIds)) {
					List<BillClassMap> billclassMaplist = billClassMapMapper.selectList(new EntityWrapper<BillClassMap>()
							.in("class_id", classIds)
							);

					if (CollectionUtils.isEmpty(billclassMaplist)) {
						return page;
					}
					List<Long> billIds = billclassMaplist.stream().map(BillClassMap::getBillId).collect(Collectors.toList());
					queryBillInfo.setBillIds(billIds);
				}
			} else {
				return page;
			}
		}

		List<BillVo> searchResult = billMapper.getBillList(page, queryBillInfo.getSearch());
		for (BillVo billVo : searchResult) {
			if (billVo.getTotal() == null) {
				billVo.setTotal(new BigDecimal(0));
			}
			if (billVo.getTotalPay() == null) {
				billVo.setTotalPay(new BigDecimal(0));
			}
		}
		page.setRecords(searchResult);
		return page;
	}

	@Override
	public List<Bill> getBillName() {

		ShiroUser currentUser = ShiroKit.getUser();
		User user = userMapper.selectById(currentUser.getId());
		Long schoolId = user.getSchoolId();
		List<Bill> selectList = null;
		if (ShiroKit.isDirector()) {
			selectList = billMapper.selectList(new EntityWrapper<Bill>()
					.eq("is_delete", 0)
					.eq("school_id", schoolId)
					.orderBy(true, "create_time", false));
		}
		else {
			selectList = billMapper.selectListWithTeacher(schoolId, user.getId());
		}
		return selectList;
	}

	@Override
	public BillVo getBillInfo(Long id) {

		ShiroUser currentUser = ShiroKit.getUser();
		User user = userMapper.selectById(currentUser.getId());
		Long schoolId = user.getSchoolId();
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("id", id);
		map.put("schoolId", schoolId);
		BillVo billVo = billMapper.getBillInfo(map);
		if (billVo == null) {
			throw new AppCheckException("school.zhangdan.bill.code", "school.zhangdan.bill.message");
		} else {
			if (billVo.getTotal() == null) {
				billVo.setTotal(new BigDecimal(0));
			}
			if (billVo.getTotalPay() == null) {
				billVo.setTotalPay(new BigDecimal(0));
			}
		}
		return billVo;
	}

	@Override
	public CountTotal getCountTotal(QueryCountTotal queryCountTotal) {

		ShiroUser currentUser = ShiroKit.getUser();
		User user = userMapper.selectById(currentUser.getId());
		Long schoolId = user.getSchoolId();
		Map<String, Object> map = new HashMap<String, Object>();
		if (queryCountTotal.getEndTime() != null) {
			queryCountTotal.getEndTime().setHours(23);
			queryCountTotal.getEndTime().setMinutes(59);
			queryCountTotal.getEndTime().setSeconds(59);
			map.put("endTime", queryCountTotal.getEndTime());
		}
		if (queryCountTotal.getStartTime() != null) {
			queryCountTotal.getStartTime().setHours(00);
			queryCountTotal.getStartTime().setMinutes(00);
			queryCountTotal.getStartTime().setSeconds(00);
			map.put("startTime", queryCountTotal.getStartTime());
		}

		map.put("schoolId", schoolId);
		if (!ShiroKit.isDirector()) {
			map.put("masterFlag", 0);
			map.put("userId", user.getId());
		}
		CountTotal countTotal = billMapper.getCountTotal(map);
		if (countTotal != null) {
			if (countTotal.getFindTotal() == null) {
				countTotal.setFindTotal(new BigDecimal(0));
			}
			if (countTotal.getTotal() == null) {
				countTotal.setTotal(new BigDecimal(0));
			}
			if (countTotal.getFindTotalPay() == null) {
				countTotal.setFindTotalPay(new BigDecimal(0));
			}
		} else {
			countTotal = new CountTotal();
			countTotal.setFindTotal(new BigDecimal(0));
			countTotal.setTotal(new BigDecimal(0));
			countTotal.setFindTotalPay(new BigDecimal(0));
		}
		return countTotal;
	}

	@Override
	public Page<UserVo> findSchoolUserList(Page<UserVo> page, QueryUserInfo queryUserInfo) {

		// 获取菜单列表
		List<Integer> roleList = ShiroKit.getUser().getRoleList();
		if (roleList == null || roleList.size() == 0) {
			ShiroKit.getSubject().logout();
			throw new AppCheckException("system.user.role.code", "system.user.role.message");
		}
		ShiroUser currentUser = ShiroKit.getUser();
		User user = userMapper.selectById(currentUser.getId());

		if (!user.getStatus().equals(SystemConstans.YES)) {
			throw new AppCheckException("school.user.notActive.code", "school.user.notActive.message");
		}
		Long schoolId = user.getSchoolId();
		switch (queryUserInfo.getType()) {
			case 1:
				// 平台类型（1，幼儿园 ）
				queryUserInfo.setSchoolId(schoolId);
				queryUserInfo.setPRoleid("6,7");
				break;
			case 2:
				// 代理商
				queryUserInfo.setAgentId(null);
				queryUserInfo.setSchoolId(schoolId);
				queryUserInfo.setPRoleid("9,11");
				break;
			case 3:
				// 员工
				queryUserInfo.setPRoleid("8,13");
				break;
			default:
				break;
		}
		List<UserVo> searchResult = userMapper.findSchoolUserList(page, queryUserInfo.getSearch());
		if (CollectionUtils.isNotEmpty(searchResult)) {
			searchResult.forEach(x -> {
				switch (queryUserInfo.getType()) {
					case 1:
						// 平台类型（1，幼儿园 ）
						if (x.getRoleid().indexOf("6") != -1) {
							x.setRoleName("学校管理员");
							SchoolInfo selectById = schoolInfoMapper.selectById(x.getSchoolId());
							if (selectById != null && selectById.getIsDelete() == 0 && StringUtils.equals(selectById.getContactTel(), x.getPhone())) {
								x.setIsBoss(SystemConstans.YES);
								x.setRoleName("园长/校长");
							}
						} else if (x.getRoleid().indexOf("7") != -1) {
							x.setRoleName("老师");
						}
						Map<String, Object> columnMap = new HashMap<String, Object>();
						columnMap.put("school_id", schoolId);
						columnMap.put("teacher_id", x.getId());
						List<TeacherClassMap> selectByMap = teacherClassMapMapper.selectByMap(columnMap);
						if (CollectionUtils.isNotEmpty(selectByMap)) {
							List<Long> classIds = selectByMap.stream().map(TeacherClassMap::getClassId).collect(Collectors.toList());
							x.setClassIds(classIds);
							List<ClassInfo> selectBatchIds = classInfoMapper.selectBatchIds(classIds);
							List<String> classNames = new ArrayList<String>();
							for (ClassInfo ci : selectBatchIds) {
								String className = ci.getName();
								if (ci.getGradeId() != null) {
									Grade grade = gradeMapper.selectById(ci.getGradeId());
									String ex = "";
									if (StringUtils.isNotBlank(className)) {
										ex = "(" + className + ")";
									}
									className = grade.getName() + ci.getOrderNum() + "班" + ex;
								}

								classNames.add(className);
							}

							x.setClassNames(classNames);
						}
						break;

				}

			});
		}
		page.setRecords(searchResult);
		return page;
	}

	/**
	 * 方法描述: [新增或者修改学校用户.]<br/>
	 * 初始作者: 钟小平<br/>
	 * 创建日期: 2018年8月20日-下午3:59:00<br/>
	 * 开始版本: 2.0.0<br/>
	 * =================================================<br/>
	 * 修改记录：1、新增代课班级<br/>
	 * 修改作者 日期 修改内容<br/>
	 * ================================================<br/>
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void addSchoolUser(AddSchoolUser addSchoolUser) {

		ShiroUser currentUser = ShiroKit.getUser();
		User user = userMapper.selectById(currentUser.getId());
		List<Role> roleList = userIsDelete(user, "addSchoolUser");

		Role role = roleList.get(0);
		Role kRole = roleList.get(1);
		if (addSchoolUser.getType() == SystemConstans.YES) {
			role = kRole;
		}
		Role pRole = roleList.get(2);
		Long schoolId = user.getSchoolId();
		if (schoolId == null) {
			throw new AppCheckException("school.user.noSchool.code", "school.user.noSchool.message");
		}

		// 校验密码不能为汉字
		String agentPasswd = addSchoolUser.getPwd();
		for (int i = 0; i < agentPasswd.length(); i++) {
			if (StringUtil.isChinese(agentPasswd.charAt(i))) {
				throw new AppCheckException("agent.passwdContainChinese.code", "agent.passwdContainChinese.message");
			}
		}

		List<User> selectList = userMapper.selectList(new EntityWrapper<User>()
				.eq("account", addSchoolUser.getPhone().trim()));
		if (selectList != null && selectList.size() > 0) {
			User queryUser = selectList.get(0);
			if (queryUser.getStatus().equals(3)) {

				queryUser.setCreateid(currentUser.getId());
				queryUser.setCreatetime(new Date());
				queryUser.setRoleid(role.getId() + "");
				queryUser.setName(addSchoolUser.getName());
				queryUser.setPhone(addSchoolUser.getPhone());
				queryUser.setDeptid(role.getDeptid());
			} else if (queryUser.getStatus().equals(1)) {
				String[] roleids = queryUser.getRoleid().split(",");
				for (String roleid : roleids) {
					// 如果该账户是老师和园长,员工管理员，则提示账户已存在
					if (role.getId().equals(Integer.parseInt(roleid))) {
						throw new AppCheckException("staff.userHaveExistError.code", "staff.userHaveExistError.message");
					} else if (kRole.getId().equals(Integer.parseInt(roleid))) {
						throw new AppCheckException("staff.userHaveExistError.code", "staff.userHaveExistError.message");
					} else if (pRole.getId().equals(Integer.parseInt(roleid))) {
						throw new AppCheckException("staff.userHaveExistError.code", "staff.userHaveExistError.message");
					}
				}
				queryUser.setRoleid(queryUser.getRoleid() + "," + role.getId());
				queryUser.setUpdateid(currentUser.getId());
				queryUser.setUpdatetime(new Date());
			}
			// 校验PID是否正确

			String salt = ShiroKit.getRandomSalt(5);
			queryUser.setPassword(ShiroKit.md5(addSchoolUser.getPwd(), salt));
			queryUser.setSalt(salt);
			queryUser.setStatus(1);
			queryUser.setSchoolId(schoolId);
			queryUser.setComment(addSchoolUser.getComment());
			// 更新账户的角色
			Integer updateById = userMapper.updateById(queryUser);
			if (updateById < 1) {
				throw new AppCheckException("staff.addUserError.code", "staff.addUserError.message");
			}

			// 代理班级
			List<Long> classIds = addSchoolUser.getClassIds();
			if (CollectionUtils.isNotEmpty(classIds)) {

				Map<String, Object> columnMap = new HashMap<String, Object>();
				columnMap.put("teacher_id", queryUser.getId());
				columnMap.put("school_id", schoolId);
				teacherClassMapMapper.deleteByMap(columnMap);

				List<TeacherClassMap> list = new ArrayList<TeacherClassMap>();
				for (Long classId : classIds) {
					ClassInfo classInfo = new ClassInfo();
					classInfo.setSchoolId(schoolId);
					classInfo.setId(classId);
					classInfo.setIsDelete(SystemConstans.NO);
					ClassInfo selectById = classInfoMapper.selectOne(classInfo);
					if (selectById == null || selectById.getIsDelete().equals(SystemConstans.YES) || !selectById.getSchoolId().equals(schoolId)) {
						throw new AppCheckException("staff.classError.code", "staff.classError.message");
					}
					TeacherClassMap tcm = new TeacherClassMap();
					tcm.setClassId(classId);
					tcm.setTeacherId(Long.parseLong(queryUser.getId() + ""));
					tcm.setCreatorId(Long.parseLong(user.getId() + ""));
					tcm.setSchoolId(schoolId);
					tcm.setCreatorRole(user.getRoleid());
					tcm.setCreateTime(new Date());
					list.add(tcm);
				}
				teacherClassMapMapper.insertBatch(list);
			}

		} else {

			String salt = ShiroKit.getRandomSalt(5);
			User myUser = new User();
			myUser.setSalt(salt);
			myUser.setName(addSchoolUser.getName());
			myUser.setStatus(1);
			myUser.setCreateid(currentUser.getId());
			myUser.setCreatetime(new Date());
			myUser.setComment(addSchoolUser.getComment());
			myUser.setPhone(addSchoolUser.getPhone());
			myUser.setAccount(addSchoolUser.getPhone());
			myUser.setSchoolId(schoolId);
			// myUser.setDeptid(role.getDeptid());
			myUser.setRoleid(role.getId() + "");
			myUser.setPassword(ShiroKit.md5(addSchoolUser.getPwd(), salt));
			myUser.setDeptid(SystemConstans.DEPT_SCHOOL_INT);
			Integer insert = userMapper.insert(myUser);
			if (insert < 1) {
				throw new AppCheckException("staff.addUserError.code", "staff.addUserError.message");
			}

			// 代理班级
			List<Long> classIds = addSchoolUser.getClassIds();
			if (CollectionUtils.isNotEmpty(classIds)) {

				Map<String, Object> columnMap = new HashMap<String, Object>();
				columnMap.put("teacher_id", myUser.getId());
				columnMap.put("school_id", schoolId);
				teacherClassMapMapper.deleteByMap(columnMap);
				List<TeacherClassMap> list = new ArrayList<TeacherClassMap>();
				for (Long classId : classIds) {
					ClassInfo classInfo = new ClassInfo();
					classInfo.setSchoolId(schoolId);
					classInfo.setId(classId);
					classInfo.setIsDelete(SystemConstans.NO);
					ClassInfo selectById = classInfoMapper.selectOne(classInfo);
					if (selectById == null || selectById.getIsDelete().equals(SystemConstans.YES) || !selectById.getSchoolId().equals(schoolId)) {
						throw new AppCheckException("staff.classError.code", "staff.classError.message");
					}
					TeacherClassMap tcm = new TeacherClassMap();
					tcm.setClassId(classId);
					tcm.setTeacherId(Long.parseLong(myUser.getId() + ""));
					tcm.setCreatorId(Long.parseLong(user.getId() + ""));
					tcm.setSchoolId(schoolId);
					tcm.setCreatorRole(user.getRoleid());
					tcm.setCreateTime(new Date());
					list.add(tcm);
				}
				teacherClassMapMapper.insertBatch(list);
			}
		}

	}

	private List<Role> userIsDelete(User user, String string) {

		String troleName = "老师";
		String kRoleName = "园长";
		String pRoleName = "员工管理员";
		String fileReason = "";
		if ("addSchoolUser".equals(string)) {
			fileReason = "无法添加用户";
		} else if ("newSendBillDetaile".equals(string)) {
			fileReason = "无法创建账单";
		}
		if (user == null || user.getStatus().equals(3)) {
			throw new AppCheckException("school.zhangdan.add.user.file.code", "school.zhangdan.add.user.file.message",
					new Object[] { "用户", fileReason });
		}
		// 查询老师角色的ID
		List<Role> troleList = roleMapper.selectList(new EntityWrapper<Role>()
				.eq("name", troleName));
		Role tRole = null;
		if (troleList != null && troleList.size() == 1) {
			tRole = troleList.get(0);
		}
		if (tRole == null) {
			throw new AppCheckException("school.user.add.code", "school.user.add.message");
		}
		// 查询园长角色的ID
		List<Role> kRoleList = roleMapper.selectList(new EntityWrapper<Role>()
				.eq("name", kRoleName));
		Role kRole = null;
		if (kRoleList != null && kRoleList.size() == 1) {
			kRole = kRoleList.get(0);
		}
		// 查询员工管理员的ID
		List<Role> pRoleList = roleMapper.selectList(new EntityWrapper<Role>()
				.eq("name", pRoleName));
		Role pRole = null;
		if (pRoleList != null && pRoleList.size() == 1) {
			pRole = pRoleList.get(0);
		}
		boolean b = true;
		for (String s : user.getRoleid().split(",")) {
			if (tRole.getId().equals(Integer.valueOf(s)) || kRole.getId().equals(Integer.valueOf(s))) {
				b = false;
				break;
			}
		}
		if (b) {
			throw new AppCheckException("school.zhangdan.add.user.file.code", "school.zhangdan.add.user.file.message",
					new Object[] { "角色", fileReason });
		}
		List<Role> roleList = new ArrayList<Role>();
		roleList.add(tRole);
		roleList.add(kRole);
		roleList.add(pRole);
		return roleList;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void deleteSchoolUser(Integer id) {

		ShiroUser currentUser = ShiroKit.getUser();
		User user = userMapper.selectById(currentUser.getId());
		Long schoolId = user.getSchoolId();
		List<Integer> roleList = currentUser.getRoleList();

		String tRoleName = "老师";
		String kRoleName = "园长";
		String pRoleName = "员工管理员";

		// 查询老师角色的ID
		List<Role> tRoleList = roleMapper.selectList(new EntityWrapper<Role>()
				.eq("name", tRoleName));
		Role tRole = null;
		if (tRoleList != null && tRoleList.size() == 1) {
			tRole = tRoleList.get(0);
		}
		// 查询园长角色的ID
		List<Role> kRoleList = roleMapper.selectList(new EntityWrapper<Role>()
				.eq("name", kRoleName));
		Role kRole = null;
		if (kRoleList != null && kRoleList.size() == 1) {
			kRole = kRoleList.get(0);
		}
		// 查询员工管理员的ID
		List<Role> pRoleList = roleMapper.selectList(new EntityWrapper<Role>()
				.eq("name", pRoleName));
		Role pRole = null;
		if (pRoleList != null && pRoleList.size() == 1) {
			pRole = pRoleList.get(0);
		}
		// 查询要删除的用户
		User myUser = userMapper.selectById(id);
		if (myUser == null || !myUser.getStatus().equals(1)) {
			throw new AppCheckException("staff.userNotExistError.code", "staff.userNotExistError.message");
		}
		String[] roleids = myUser.getRoleid().split(",");
		int Pupdate = 0;
		int Kupdate = 0;
		int KTupdate = 0;
		// 只有管理员和园长才可以删除用户
		for (Integer role : roleList) {
			if (pRole.getId().equals(role)
					|| kRole.getId().equals(role)
					|| tRole.getId().equals(role)) {
				if (pRole.getId().equals(role)) {
					if (currentUser.getAccount().equals("ledipay")) {
						// 管理员用户不可以删除
						if (myUser.getAccount().equals("ledipay")) {
							throw new AppCheckException("school.user.delete.kindergarten.code",
									"school.user.delete.kindergarten.code", "管理员");
						}
						// 员工的角色只有一个，不做多角色处理
						myUser.setStatus(3);
						myUser.setSchoolId(null);
						myUser.setAgentId(null);
						myUser.setAlipayPid(null);
						Pupdate = userMapper.updateById(myUser);
						if (Pupdate != 1) {
							throw new AppCheckException("school.user.delete.code", "school.user.delete.message");
						}
					} else {
						throw new AppCheckException("school.user.delete.staff.code", "school.user.delete.staff.message",
								new Object[] { "管理员", "管理员" });
					}
				} else if (kRole.getId().equals(role)) {
					if (roleids.length == 1) {
						// 园长不可以删除园长的账户
						if (kRole.getId().equals(Integer.parseInt(roleids[0]))) {

							if (!ShiroKit.isDirector()) {
								throw new AppCheckException("school.user.delete.kindergarten.code",
										"school.user.delete.kindergarten.message", "管理员");
							}

							myUser.setStatus(3);
							myUser.setUpdateid(currentUser.getId());
							myUser.setUpdatetime(new Date());
							myUser.setSchoolId(null);
							myUser.setAlipayPid(null);
							Kupdate = userMapper.update(myUser, new EntityWrapper<User>()
									.eq("school_id", schoolId)
									.eq("id", id));

							if (Kupdate != 1) {
								throw new AppCheckException("school.user.delete.code", "school.user.delete.message");
							}

						} else if (tRole.getId().equals(Integer.parseInt(roleids[0]))) {
							myUser.setStatus(3);
							myUser.setUpdateid(currentUser.getId());
							myUser.setUpdatetime(new Date());
							myUser.setSchoolId(null);
							myUser.setAlipayPid(null);
							Kupdate = userMapper.update(myUser, new EntityWrapper<User>()
									.eq("school_id", schoolId)
									.eq("id", id));

							if (Kupdate != 1) {
								throw new AppCheckException("school.user.delete.code", "school.user.delete.message");
							}
						}
					} else {
						for (String roleid : roleids) {
							if (kRole.getId().equals(Integer.parseInt(roleid))) {
								if (!ShiroKit.isDirector()) {
									throw new AppCheckException("school.user.delete.kindergarten.code",
											"school.user.delete.kindergarten.message", "管理员");
								}
							} else if (tRole.getId().equals(Integer.parseInt(roleid))) {
								String myRoleids = "";
								for (String myRoleid : roleids) {
									if (!tRole.getId().equals(Integer.parseInt(myRoleid))) {
										if ("".equals(myRoleids)) {
											myRoleids += myRoleid;
										} else {
											myRoleids += "," + myRoleid;
										}
									}

								}
								myUser.setRoleid(myRoleids);
								myUser.setSchoolId(null);
								myUser.setAlipayPid(null);
								myUser.setUpdateid(currentUser.getId());
								myUser.setUpdatetime(new Date());
								KTupdate = userMapper.update(myUser, new EntityWrapper<User>()
										.eq("school_id", schoolId)
										.eq("id", id));
								if (KTupdate != 1) {
									throw new AppCheckException("school.user.delete.code", "school.user.delete.message");
								}
							}
						}
					}
				} else if (tRole.getId().equals(Integer.parseInt(roleids[0]))) {
					throw new AppCheckException("school.user.delete.staff.code", "school.user.delete.staff.message",
							new Object[] { "管理员", "管理员" });
				}
			}
		}
		if (Pupdate == 0 && Kupdate == 0 && KTupdate == 0) {
			throw new AppCheckException("school.user.delete.role.code", "school.user.delete.role.message");
		}
		// 删除账号重新登录
		String account = myUser.getAccount();
		String key = SystemConstans.USER_SESSION_CHANGE.replaceAll("\\{0\\}", account);
		keyValueDAO.set(key, SystemConstans.USER_ACOUNT_STATUS_1, 0L);
	}

	@Override
	public UserVo getSchoolUser() {

		ShiroUser currentUser = ShiroKit.getUser();
		UserVo user = userMapper.getSchoolUser(currentUser.getId());
		SortedMap<String, String> finalpackage = new TreeMap<String, String>();
		finalpackage.put("userId", user.getId() + "");
		finalpackage.put("schoolId", user.getSchoolId() + "");
		finalpackage.put("key", user.getPassword());
		log.error("--------------签名入参：" + finalpackage.toString());
		String paySign = PayUtil.createSign(finalpackage);
		user.setComments(paySign);
		user.setId(null);
		user.setPassword(null);
		UserVo schoolInfo = schoolInfoMapper.querySchoolInfo(user.getSchoolId());
		user.setSchoolProvinceName(schoolInfo.getSchoolProvinceName());
		user.setSchoolCityName(schoolInfo.getSchoolCityName());
		user.setSchoolDistrictName(schoolInfo.getSchoolDistrictName());
		user.setSchoolContactPeople(schoolInfo.getSchoolContactPeople());
		user.setContactTel(schoolInfo.getContactTel());
		user.setSchoolSubMchId(schoolInfo.getSchoolSubMchId());
		user.setSchoolAlipayNumber(schoolInfo.getSchoolAlipayNumber());
		user.setAlipayPid(schoolInfo.getAlipayPid());
		user.setSchoolMailBox(schoolInfo.getSchoolMailBox());
		String freeMonth = schoolInfo.getFreeMonth();
		if (StringUtil.isNoneBlank(freeMonth)) {
			user.setFreeMonth(freeMonth.substring(0, freeMonth.lastIndexOf(",")));
		}
		user.setGiveCount(schoolInfo.getGiveCount());
		return user;
	}

	public String cellConversionString(Cell cell) {

		String name = "";
		Double nameDouble = null;
		try {
			name = cell.getStringCellValue().toString();

		} catch (Exception e) {
			nameDouble = cell.getNumericCellValue();
		}
		if (!"".equals(name)) {
			name = String.valueOf(name);
			return name.toLowerCase().trim();
		} else if (nameDouble != null) {
			DecimalFormat df = new DecimalFormat("0");
			name = df.format(nameDouble);
			return name.toLowerCase().trim();
		}
		return "";

	}

	public void insertBillDetailList(Bill bill, String role, Integer creatorId, Long schoolId,
			List<BillDetail> billDetailList,
			List<ClassInfo> classInfoList,
			List<Long> schoolPayItems) {

		if (schoolPayItems.size() > SystemConstans.ITEM_LIMIT) {
			throw new AppCheckException("school.schoolPayItem.limit.code", "school.schoolPayItem.limit.message", SystemConstans.ITEM_LIMIT);
		}
		for (int i = 0; i < billDetailList.size(); i++) {
			BillDetail billDetail = billDetailList.get(i);
			ClassInfo classInfo = classInfoList.get(i);
			// 添加订单明细
			String billDetailId = PayUtil.getBillDetailId();
			boolean isBillDetailId = true;
			do {
				// 校验账单是否可用
				List<BillDetail> queryBillDetailList = billDetailMapper
						.selectList(new EntityWrapper<BillDetail>()
								.eq("is_delete", 0)
								.eq("bill_detail_id", billDetailId));
				if (queryBillDetailList == null || queryBillDetailList.size() == 0) {
					isBillDetailId = false;
					break;
				}
				billDetailId = PayUtil.getBillDetailId();
			} while (isBillDetailId);
			billDetail.setBillDetailId(billDetailId);
			billDetail.setBillId(bill.getId());
			billDetail.setSchoolId(schoolId);
			billDetail.setClassId(classInfo.getId());
			billDetail.setBillStatus(SystemConstans.BILL_STATUS_UNSEND);
			billDetail.setPayWay(SystemConstans.PAY_WAY_ALI);
			billDetail.setIsDelete(0);
			billDetail.setCreateTime(new Date());
			billDetail.setCreatorId(Long.valueOf(creatorId));
			billDetail.setCreatorRole(role);

			// 添加账单明细表
			int insertBillDetail = billDetailMapper.insert(billDetail);
			if (insertBillDetail < 1) {
				throw new AppCheckException("school.zhangdan.import.code", "school.zhangdan.import.message");
			}
		}

		List<Long> classIds = classInfoList.stream().map(ClassInfo::getId).distinct().collect(Collectors.toList());
		List<BillClassMap> billClassList = new ArrayList<BillClassMap>();
		for (Long cid : classIds) {
			BillClassMap bcm = new BillClassMap();
			bcm.setBillId(bill.getId());
			bcm.setClassId(cid);
			bcm.setCreatorId(Long.valueOf(creatorId));
			bcm.setCreateTime(new Date());
			bcm.setCreatorRole(role);
			billClassList.add(bcm);
		}
		// 账单缴费班级关系
		billClassMapMapper.insertBatch(billClassList);
		List<BillItemMap> billItemMapList = new ArrayList<BillItemMap>();

		// 必选金额
		BigDecimal needSelected = new BigDecimal(0);
		Boolean selected = false;
		for (Long itemId : schoolPayItems) {

			SchoolPayItem selectOne = schoolPayItemMapper.selectById(itemId);

			if (selectOne == null) {
				throw new AppCheckException("school.schoolPayItem.noExit.code", "school.schoolPayItem.noExit.message", itemId);
			}

			if (selectOne.getFlag().equals(SystemConstans.YES)) {
				selected = true;
			}

			BigDecimal money = selectOne.getMoney();
			if (selectOne.getFlag() == SystemConstans.TWO) {
				money = money.negate();
			}
			if (selectOne.getFlag() > 0) {
				needSelected = needSelected.add(money);
			}
			BillItemMap bim = new BillItemMap();
			bim.setBillId(bill.getId());
			bim.setCreatorId(Long.valueOf(creatorId));
			bim.setCreateTime(new Date());
			bim.setCreatorRole(role);
			bim.setItemId(itemId);
			billItemMapList.add(bim);
		}
		if (!selected) {
			throw new AppCheckException("school.schoolPayItem.bill.selected.code", "school.schoolPayItem.bill.selected.message");
		}
		if (needSelected.compareTo(new BigDecimal(0)) <= 0) {
			throw new AppCheckException("school.schoolPayItem.bill.oversized.code", "school.schoolPayItem.bill.oversized.message");
		}
		// 账单缴费项目关系
		billItemMapMapper.insertBatch(billItemMapList);
	}

	/**
	 * 方法描述: [线下缴费.]<br/>
	 * 初始作者: 钟小平<br/>
	 * 创建日期: 2018年7月6日-下午2:44:10<br/>
	 * 开始版本: 2.0.0<br/>
	 * =================================================<br/>
	 * 修改记录：<br/>
	 * 修改作者 日期 修改内容<br/>
	 * ================================================<br/>
	 */
	@Override
	@Transactional
	public void offlinePayment(OfflinePayment offlinePayment) {

		ShiroUser currentUser = ShiroKit.getUser();
		User user = userMapper.selectById(currentUser.getId());
		if (!user.getStatus().equals(SystemConstans.YES)) {
			throw new AppCheckException("school.user.notActive.code", "school.user.notActive.message");
		}
		if (user.getSchoolId() == null) {
			throw new AppCheckException("school.user.noSchool.code", "school.user.noSchool.message");
		}
		Bill entity = new Bill();
		entity.setCreatorId(Long.parseLong(currentUser.getId() + ""));
		entity.setCreateTime(new Date());
		entity.setCreatorRole(user.getRoleid());
		entity.setName(SystemConstans.BILL_NAME);
		entity.setIsDelete(0);
		entity.setBillEndTime(new Date());
		entity.setTotal(offlinePayment.getTotal());
		// 全部成功
		entity.setIsSuccess(SystemConstans.NO);
		entity.setTotalPay(offlinePayment.getTotal());
		entity.setComment(offlinePayment.getComment());
		entity.setSchoolId(user.getSchoolId());
		entity.setBillEndTime(new Date());
		entity.setBillNumber(IdGenerator.getId());
		billMapper.insert(entity);
		BillDetail entityDetail = new BillDetail();
		entityDetail.setBillId(entity.getId());
		ClassInfo selectById = classInfoMapper.selectById(offlinePayment.getClassId());
		if (selectById != null) {
			entityDetail.setClassId(offlinePayment.getClassId());
		} else {
			throw new AppCheckException("school.class.notexit.code", "school.class.notexit.message");
		}
		// 账单详情id
		entityDetail.setBillDetailId(PayUtil.getBillDetailId());
		entityDetail.setBillStatus(SystemConstans.BILL_STATUS_FINISH);
		entityDetail.setSchoolId(user.getSchoolId());
		entityDetail.setTotalDetail(offlinePayment.getTotal());
		String childId = offlinePayment.getChildName();
		Student student = studentMapper.selectById(childId);
		entityDetail.setStudentName(student.getName());
		entityDetail.setParentMobile(offlinePayment.getParentMobile());
		entityDetail.setBillDetailBeginTime(new Date());
		switch (offlinePayment.getPayWay()) {
			case 0:
				entityDetail.setPayWay(SystemConstans.PAY_WAY_CASH);
				break;
			case 1:
				entityDetail.setPayWay(SystemConstans.PAY_WAY_GIRO);
				break;
			case 2:
				entityDetail.setPayWay(SystemConstans.PAY_WAY_OTHER);
				break;

			default:
				break;
		}
		entityDetail.setComment(offlinePayment.getComment());
		entityDetail.setIsDelete(SystemConstans.NO);
		entityDetail.setCreateTime(new Date());
		entityDetail.setCreatorId(Long.valueOf(user.getId()));
		entityDetail.setCreatorRole(user.getRoleid());
		entityDetail.setPayTime(new Date());
		billDetailMapper.insert(entityDetail);

	}

	private void extracted(DownloadBillDetailExcel query) {

		if (query.getStartTime() != null) {
			query.setStartTime(DateUtil.formate(query.getStartTime(), true));
		}
		if (query.getEndTime() != null) {
			query.setEndTime(DateUtil.formate(query.getEndTime(), false));
		}
	}

	private void extracted(QueryBillInfo query) {

		if (query.getStartTime() != null) {
			query.setStartTime(DateUtil.formate(query.getStartTime(), true));
		}
		if (query.getEndTime() != null) {
			query.setEndTime(DateUtil.formate(query.getEndTime(), false));
		}
	}

	/**
	 * 方法描述: [修改学校用户]<br/>
	 * 初始作者: 钟小平<br/>
	 * 创建日期: 2018年8月21日-上午11:09:11<br/>
	 * 开始版本: 2.0.0<br/>
	 * =================================================<br/>
	 * 修改记录：<br/>
	 * 修改作者 日期 修改内容<br/>
	 * ================================================<br/>
	 */
	@Override
	@Transactional
	public void mergeSchoolUser(AddSchoolUser addSchoolUser) {

		ShiroUser currentUser = ShiroKit.getUser();
		User user = userMapper.selectById(currentUser.getId());
		if (!user.getStatus().equals(SystemConstans.YES)) {
			throw new AppCheckException("school.user.notActive.code", "school.user.notActive.message");
		}
		Long schoolId = user.getSchoolId();
		if (schoolId == null) {
			throw new AppCheckException("school.user.noSchool.code", "school.user.noSchool.message");
		}
		User mergeUser = userMapper.selectById(addSchoolUser.getId());
		if (!mergeUser.getStatus().equals(SystemConstans.YES)) {
			throw new AppCheckException("school.user.notActive.code", "school.user.notActive.message");
		}
		List<Role> roleList = userIsDelete(user, "addSchoolUser");
		Role role = roleList.get(0);
		Role kRole = roleList.get(1);
		if (addSchoolUser.getType() == SystemConstans.YES) {
			role = kRole;
		}
		if (mergeUser.getStatus().equals(3)) {

			mergeUser.setCreateid(currentUser.getId());
			mergeUser.setCreatetime(new Date());
			mergeUser.setRoleid(role.getId() + "");
			mergeUser.setName(addSchoolUser.getName());
			mergeUser.setPhone(addSchoolUser.getPhone());
			mergeUser.setDeptid(role.getDeptid());
		} else if (mergeUser.getStatus().equals(1)) {

			mergeUser.setUpdateid(currentUser.getId());
			mergeUser.setUpdatetime(new Date());
		}
		mergeUser.setStatus(1);
		mergeUser.setName(addSchoolUser.getName());
		mergeUser.setSchoolId(schoolId);
		mergeUser.setComment(addSchoolUser.getComment());
		mergeUser.setVersion(addSchoolUser.getVersion());
		// 更新账户的角色
		Integer updateById = userMapper.updateById(mergeUser);
		if (updateById < 1) {
			throw new AppCheckException("staff.updateUserError.code", "staff.updateUserError.message");
		}
		// 代理班级
		List<Long> classIds = addSchoolUser.getClassIds();
		Map<String, Object> columnMap = new HashMap<String, Object>();
		columnMap.put("teacher_id", mergeUser.getId());
		columnMap.put("school_id", schoolId);
		teacherClassMapMapper.deleteByMap(columnMap);
		if (CollectionUtils.isNotEmpty(classIds)) {
			List<TeacherClassMap> list = new ArrayList<TeacherClassMap>();
			for (Long classId : classIds) {

				ClassInfo classInfo = new ClassInfo();
				classInfo.setSchoolId(schoolId);
				classInfo.setId(classId);
				classInfo.setIsDelete(SystemConstans.NO);
				ClassInfo selectById = classInfoMapper.selectOne(classInfo);
				if (selectById == null || selectById.getIsDelete().equals(SystemConstans.YES) || !selectById.getSchoolId().equals(schoolId)) {
					throw new AppCheckException("staff.classError.code", "staff.classError.message");
				}
				TeacherClassMap tcm = new TeacherClassMap();
				tcm.setClassId(classId);
				tcm.setTeacherId(Long.parseLong(mergeUser.getId() + ""));
				tcm.setCreatorId(Long.parseLong(user.getId() + ""));
				tcm.setSchoolId(schoolId);
				tcm.setCreatorRole(user.getRoleid());
				tcm.setCreateTime(new Date());
				list.add(tcm);
			}
			teacherClassMapMapper.insertBatch(list);
		}

	}

	/**
	 * 方法描述: [当面付账单列表.]<br/>
	 * 初始作者: 钟小平<br/>
	 * 创建日期: 2018年8月22日-下午12:01:30<br/>
	 * 开始版本: 2.0.0<br/>
	 * =================================================<br/>
	 * 修改记录：<br/>
	 * 修改作者 日期 修改内容<br/>
	 * ================================================<br/>
	 */
	@Override
	public Page<Bill> findFaceBillList(Page<Bill> page, FaceQueryBillInfo queryBillInfo) {

		ShiroUser currentUser = ShiroKit.getUser();
		User oneUser = userMapper.selectById(currentUser.getId());
		if (!oneUser.getStatus().equals(SystemConstans.YES)) {
			throw new AppCheckException("school.user.notActive.code", "school.user.notActive.message");
		}
		Long schoolId = oneUser.getSchoolId();
		if (schoolId == null) {
			throw new AppCheckException("school.user.noSchool.code", "school.user.noSchool.message");
		}
		queryBillInfo.setSchoolId(schoolId);
		if (!ShiroKit.isDirector()) {
			Map<String, Object> columnMap = new HashMap<String, Object>();
			columnMap.put("school_id", schoolId);
			columnMap.put("teacher_id", oneUser.getId());
			List<TeacherClassMap> selectByMap = teacherClassMapMapper.selectByMap(columnMap);
			if (CollectionUtils.isNotEmpty(selectByMap)) {
				List<Long> classIds = selectByMap.stream().map(TeacherClassMap::getClassId).collect(Collectors.toList());

				if (CollectionUtils.isNotEmpty(classIds)) {
					List<BillClassMap> billclassMaplist = billClassMapMapper.selectList(new EntityWrapper<BillClassMap>()
							.in("class_id", classIds)
							);

					if (CollectionUtils.isEmpty(billclassMaplist)) {
						return page;
					}
					List<Long> billIds = billclassMaplist.stream().map(BillClassMap::getBillId).collect(Collectors.toList());
					queryBillInfo.setBillIds(billIds);
				}
			} else {
				return page;
			}
		}

		List<Bill> searchResult = billMapper.pageFaceList(page, queryBillInfo.getSearch());
		page.setRecords(searchResult);
		return page;
	}

	/**
	 * 方法描述: [创建账单.]<br/>
	 * 初始作者: 钟小平<br/>
	 * 创建日期: 2018年8月22日-下午1:23:51<br/>
	 * 开始版本: 2.0.0<br/>
	 * =================================================<br/>
	 * 修改记录：<br/>
	 * 修改作者 日期 修改内容<br/>
	 * ================================================<br/>
	 */
	@Override
	@Transactional
	public Long createFaceBillDetaile(Face2FaceBill face2FaceBill, int billType) {

		ShiroUser currentUser = ShiroKit.getUser();
		User oneUser = userMapper.selectById(currentUser.getId());
		if (!oneUser.getStatus().equals(SystemConstans.YES)) {
			throw new AppCheckException("school.user.notActive.code", "school.user.notActive.message");
		}
		Long schoolId = oneUser.getSchoolId();
		String roleid = oneUser.getRoleid();
		if (schoolId == null) {
			throw new AppCheckException("school.user.noSchool.code", "school.user.noSchool.message");
		}
		Long createId = Long.valueOf(currentUser.getId());

		// 账单id
		Long billId = face2FaceBill.getBillId();
		if (billId != null) {
			Bill billItem = new Bill();
			billItem.setId(billId);
			// billItem.setIsDelete(SystemConstans.NO);
			billItem.setSchoolId(schoolId);
			Bill updateBill = billMapper.selectOne(billItem);
			if (updateBill == null) {
				throw new AppCheckException("school.zhangdan.notExitorOverTime.code", "school.zhangdan.notExitorOverTime.message");
			}
			// 校验截止时间
			if (new Date().after(updateBill.getBillEndTime())) {
				throw new AppCheckException("school.zhangdan.notExitorOverTime.code", "school.zhangdan.notExitorOverTime.message");
			}
			// 缴费班级
			List<Long> classIds = face2FaceBill.getClassIds();
			List<BillClassMap> billClassList = new ArrayList<BillClassMap>();
			for (Long classId : classIds) {
				ClassInfo entity = new ClassInfo();
				entity.setId(classId);
				entity.setIsDelete(SystemConstans.NO);
				entity.setSchoolId(schoolId);
				ClassInfo selectOne = classInfoMapper.selectOne(entity);
				if (selectOne == null) {
					throw new AppCheckException("school.class.noExit.code", "school.class.noExit.message", classId);
				}
				Map<String, Object> columnMap = new HashMap<String, Object>();
				columnMap.put("bill_id", billId);
				billClassMapMapper.deleteByMap(columnMap);
				BillClassMap cm = new BillClassMap();
				cm.setBillId(billId);
				cm.setClassId(classId);
				cm.setCreateTime(new Date());
				cm.setCreatorRole(roleid);
				cm.setCreatorId(createId);
				billClassList.add(cm);
			}

			if (CollectionUtils.isNotEmpty(billClassList)) {
				billClassMapMapper.insertBatch(billClassList);
			}
			// 缴费项目
			List<Long> schoolPayItemIds = face2FaceBill.getSchoolPayItemIds();
			if (CollectionUtils.isNotEmpty(schoolPayItemIds)) {

				if (schoolPayItemIds.size() > SystemConstans.ITEM_LIMIT) {
					throw new AppCheckException("school.schoolPayItem.limit.code", "school.schoolPayItem.limit.message", SystemConstans.ITEM_LIMIT);
				}

				List<BillItemMap> billItemMapList = new ArrayList<BillItemMap>();
				// 必选金额
				BigDecimal needSelected = new BigDecimal(0);
				Boolean selected = false;
				for (Long schoolPayItemId : schoolPayItemIds) {
					SchoolPayItem entity = new SchoolPayItem();
					entity.setId(schoolPayItemId);
					entity.setSchoolId(schoolId);
					entity.setIsDelete(SystemConstans.NO);
					SchoolPayItem selectOne = schoolPayItemMapper.selectOne(entity);
					if (selectOne == null) {
						throw new AppCheckException("school.schoolPayItem.noExit.code", "school.schoolPayItem.noExit.message", schoolPayItemId);
					}

					if (selectOne.getFlag().equals(SystemConstans.YES)) {
						selected = true;
					}
					Map<String, Object> columnMap = new HashMap<String, Object>();
					columnMap.put("bill_id", billId);
					billItemMapMapper.deleteByMap(columnMap);
					BigDecimal money = selectOne.getMoney();
					if (selectOne.getFlag() == SystemConstans.TWO) {
						money = money.negate();
					}
					if (selectOne.getFlag() > 0) {
						needSelected = needSelected.add(money);
					}
					BillItemMap bm = new BillItemMap();
					bm.setBillId(billId);
					bm.setItemId(schoolPayItemId);
					bm.setCreateTime(new Date());
					bm.setCreatorRole(roleid);
					bm.setCreatorId(createId);
					billItemMapList.add(bm);
				}

				if (!selected) {
					throw new AppCheckException("school.schoolPayItem.bill.selected.code", "school.schoolPayItem.bill.selected.message");
				}
				if (needSelected.compareTo(new BigDecimal(0)) <= 0) {
					throw new AppCheckException("school.schoolPayItem.bill.oversized.code", "school.schoolPayItem.bill.oversized.message", billId);
				}
				if (CollectionUtils.isNotEmpty(billItemMapList)) {
					billItemMapMapper.insertBatch(billItemMapList);
				}
			}
			if (StringUtils.isNotBlank(face2FaceBill.getBillName()) && face2FaceBill.getBillEndTime() != null) {
				updateBill.setName(face2FaceBill.getBillName());
				updateBill.setBillEndTime(face2FaceBill.getBillEndTime());
				updateBill.setUpdateTime(new Date());
				updateBill.setUpdaterId(Long.parseLong(oneUser.getId() + ""));
				billMapper.updateById(updateBill);
			}

			return billId;
		}
		// 校验截止时间
		if (new Date().after(face2FaceBill.getBillEndTime())) {
			throw new AppCheckException("school.zhangdan.billEndTime.code", "school.zhangdan.billEndTime.message");
		}
		// 插入账单表，生成ID
		Bill bill = new Bill();
		bill.setName(face2FaceBill.getBillName());
		bill.setBillEndTime(face2FaceBill.getBillEndTime());
		if (billType == SystemConstans.YES) {
			bill.setIsDelete(SystemConstans.YES);
		} else {
			bill.setIsDelete(SystemConstans.NO);
		}
		bill.setCreateTime(new Date());

		bill.setCreatorId(createId);

		bill.setCreatorRole(roleid);
		// 当面付账单
		bill.setBillType(billType);
		bill.setBillNumber(IdGenerator.getId());
		bill.setSchoolId(schoolId);
		billMapper.insert(bill);
		// 缴费班级
		List<Long> classIds = face2FaceBill.getClassIds();
		List<BillClassMap> billClassList = new ArrayList<BillClassMap>();
		for (Long classId : classIds) {
			ClassInfo entity = new ClassInfo();
			entity.setId(classId);
			entity.setIsDelete(SystemConstans.NO);
			entity.setSchoolId(schoolId);
			ClassInfo selectOne = classInfoMapper.selectOne(entity);
			if (selectOne == null) {
				throw new AppCheckException("school.class.noExit.code", "school.class.noExit.message", classId);
			}

			BillClassMap cm = new BillClassMap();
			cm.setBillId(bill.getId());
			cm.setClassId(classId);
			cm.setCreateTime(new Date());
			cm.setCreatorRole(roleid);
			cm.setCreatorId(createId);
			billClassList.add(cm);
		}
		billClassMapMapper.insertBatch(billClassList);
		// 缴费项目
		List<Long> schoolPayItemIds = face2FaceBill.getSchoolPayItemIds();
		if (schoolPayItemIds.size() > SystemConstans.ITEM_LIMIT) {
			throw new AppCheckException("school.schoolPayItem.limit.code", "school.schoolPayItem.limit.message", SystemConstans.ITEM_LIMIT);
		}
		List<BillItemMap> billItemMapList = new ArrayList<BillItemMap>();
		// 必选金额
		BigDecimal needSelected = new BigDecimal(0);
		Boolean selected = false;
		for (Long schoolPayItemId : schoolPayItemIds) {
			SchoolPayItem entity = new SchoolPayItem();
			entity.setId(schoolPayItemId);
			entity.setSchoolId(schoolId);
			entity.setIsDelete(SystemConstans.NO);
			SchoolPayItem selectOne = schoolPayItemMapper.selectOne(entity);
			if (selectOne == null) {
				throw new AppCheckException("school.schoolPayItem.noExit.code", "school.schoolPayItem.noExit.message", schoolPayItemId);
			}

			if (selectOne.getFlag().equals(SystemConstans.YES)) {
				selected = true;
			}
			BigDecimal money = selectOne.getMoney();
			if (selectOne.getFlag() == SystemConstans.TWO) {
				money = money.negate();
			}
			if (selectOne.getFlag() > 0) {
				needSelected = needSelected.add(money);
			}
			BillItemMap bm = new BillItemMap();
			bm.setBillId(bill.getId());
			bm.setItemId(schoolPayItemId);
			bm.setCreateTime(new Date());
			bm.setCreatorRole(roleid);
			bm.setCreatorId(createId);
			billItemMapList.add(bm);
		}
		if (!selected) {
			throw new AppCheckException("school.schoolPayItem.bill.selected.code", "school.schoolPayItem.bill.selected.message", bill.getId());
		}
		if (needSelected.compareTo(new BigDecimal(0)) <= 0) {
			throw new AppCheckException("school.schoolPayItem.bill.oversized.code", "school.schoolPayItem.bill.oversized.message", bill.getId());
		}

		billItemMapMapper.insertBatch(billItemMapList);
		return bill.getId();
	}

	/**
	 * 方法描述: [在线账单列表.]<br/>
	 * 初始作者: 钟小平<br/>
	 * 创建日期: 2018年8月27日-下午3:48:12<br/>
	 * 开始版本: 2.0.0<br/>
	 * =================================================<br/>
	 * 修改记录：<br/>
	 * 修改作者 日期 修改内容<br/>
	 * ================================================<br/>
	 */
	@Override
	public OnlineVo billClassSchoolItemList(Long billId) {

		ShiroUser currentUser = ShiroKit.getUser();
		User user = userMapper.selectById(currentUser.getId());
		if (!user.getStatus().equals(SystemConstans.YES)) {
			throw new AppCheckException("school.user.notActive.code", "school.user.notActive.message");
		}
		Long schoolId = user.getSchoolId();
		if (schoolId == null) {
			throw new AppCheckException("school.user.noSchool.code", "school.user.noSchool.message");
		}
		List<LinkedHashMap<String, Object>> list = billItemMapMapper.billClassSchoolItemList(billId, schoolId);

		OnlineVo vo = new OnlineVo();
		if (CollectionUtils.isNotEmpty(list)) {
			Set<String> keySet = list.get(0).keySet();
			vo.setTitleSet(keySet);
			Collection<Object> coll = new ArrayList<Object>();

			for (HashMap<String, Object> entry : list) {
				coll.add(entry.values());
			}
			vo.setTableSet(coll);

		}
		return vo;
	}

	/**
	 * 方法描述: [删除缴费班级.]<br/>
	 * 初始作者: 钟小平<br/>
	 * 创建日期: 2018年8月27日-下午7:51:04<br/>
	 * 开始版本: 2.0.0<br/>
	 * =================================================<br/>
	 * 修改记录：<br/>
	 * 修改作者 日期 修改内容<br/>
	 * ================================================<br/>
	 */
	@Override
	@Transactional
	public void removeClassBillItem(Long id) {

		billClassMapMapper.deleteById(id);
	}

	/**
	 * 方法描述: [生成账单明细.]<br/>
	 * 初始作者: 钟小平<br/>
	 * 创建日期: 2018年8月27日-下午8:16:03<br/>
	 * 开始版本: 2.0.0<br/>
	 * =================================================<br/>
	 * 修改记录：<br/>
	 * 修改作者 日期 修改内容<br/>
	 * ================================================<br/>
	 */
	@Override
	@Transactional
	public Long createBillDetill(QueryBillDetaile queryBillDetaile) {

		ShiroUser currentUser = ShiroKit.getUser();
		User user = userMapper.selectById(currentUser.getId());
		if (!user.getStatus().equals(SystemConstans.YES)) {
			throw new AppCheckException("school.user.notActive.code", "school.user.notActive.message");
		}
		Long schoolId = user.getSchoolId();
		if (schoolId == null) {
			throw new AppCheckException("school.user.noSchool.code", "school.user.noSchool.message");
		}
		List<BillClassMap> selectBatchIds = billClassMapMapper.selectBatchIds(queryBillDetaile.getBillClassIds());
		Long billId = null;
		if (CollectionUtils.isNotEmpty(selectBatchIds)) {
			billId = selectBatchIds.get(0).getBillId();
			Bill bill = new Bill();
			bill.setId(billId);
			bill.setName(queryBillDetaile.getBillName());
			bill.setBillEndTime(queryBillDetaile.getBillEndTime());
			// 校验截止时间
			if (new Date().after(queryBillDetaile.getBillEndTime())) {
				throw new AppCheckException("school.zhangdan.billEndTime.code", "school.zhangdan.billEndTime.message");
			}

			// 应缴人数
			Integer studentNum = 0;
			for (BillClassMap bcm : selectBatchIds) {

				Map<String, Object> columnMap = new HashMap<String, Object>();
				columnMap.put("class_id", bcm.getClassId());
				columnMap.put("school_id", schoolId);
				columnMap.put("is_delete", SystemConstans.NO);
				List<Student> students = studentMapper.selectByMap(columnMap);
				List<BillDetail> listBillDetill = new ArrayList<BillDetail>();
				if (CollectionUtils.isEmpty(students)) {

					ClassInfo selectById = classInfoMapper.selectById(bcm.getClassId());
					throw new AppCheckException("school.zhangdan.class.student.null.code", "school.zhangdan.class.student.null.message", selectById.getName());
				}
				for (Student s : students) {
					BillDetail bd = new BillDetail();
					bd.setBillId(billId);
					bd.setBillStatus(SystemConstans.BILL_STATUS_UNSEND);
					bd.setBillDetailId(IdGenerator.getId());
					bd.setClassId(bcm.getClassId());
					bd.setSchoolId(schoolId);
					bd.setPayWay(SystemConstans.PAY_WAY_ALI);
					bd.setIsDelete(0);
					bd.setCreateTime(new Date());
					bd.setCreatorId(Long.valueOf(user.getId()));
					bd.setCreatorRole(user.getRoleid());

					bd.setStudentName(s.getName());
					bd.setParentMobile(s.getParentMobile());
					// 订单收费项明细
					List<SchoolPayItem> schoolPayItems = schoolPayItemMapper.selectByBillId(billId, schoolId);
					BigDecimal totalDetail = new BigDecimal(0);

					// 必选金额
					BigDecimal needSelected = new BigDecimal(0);
					if (schoolPayItems.size() != 0) {
						for (SchoolPayItem item : schoolPayItems) {
							BigDecimal money = item.getMoney();
							if (item.getFlag() == SystemConstans.TWO) {
								money = money.negate();
							}
							if (item.getFlag() > 0) {
								needSelected = needSelected.add(money);
							}
							totalDetail = totalDetail.add(money);
						}
						if (needSelected.compareTo(new BigDecimal(0)) <= 0) {
							throw new AppCheckException("school.schoolPayItem.bill.oversized.code", "school.schoolPayItem.bill.oversized.message");
						}
					} else {
						throw new AppCheckException("school.schoolPayItem.bill.noExit.code", "school.schoolPayItem.bill.noExit.message");
					}
					bd.setPayItem(JSON.toJSONString(schoolPayItems));
					listBillDetill.add(bd);
					studentNum++;
				}
				billDetailMapper.insertBatch(listBillDetill);

			}

			// 更新账单信息
			bill.setStudentNum(studentNum);
			bill.setIsDelete(SystemConstans.NO);
			billMapper.updateById(bill);

		}

		return billId;
	}

	/**
	 * 方法描述: [账单班级收费项.]<br/>
	 * 初始作者: 钟小平<br/>
	 * 创建日期: 2018年9月3日-下午3:07:18<br/>
	 * 开始版本: 2.0.0<br/>
	 * =================================================<br/>
	 * 修改记录：<br/>
	 * 修改作者 日期 修改内容<br/>
	 * ================================================<br/>
	 */
	@Override
	public BillClassSchoolItemVo getBillClassSchoolItem(Long billId) {

		ShiroUser currentUser = ShiroKit.getUser();
		User user = userMapper.selectById(currentUser.getId());
		if (!user.getStatus().equals(SystemConstans.YES)) {
			throw new AppCheckException("school.user.notActive.code", "school.user.notActive.message");
		}
		Long schoolId = user.getSchoolId();
		if (schoolId == null) {
			throw new AppCheckException("school.user.noSchool.code", "school.user.noSchool.message");
		}
		BillClassSchoolItemVo vo = new BillClassSchoolItemVo();
		Bill bill = billMapper.selectById(billId);
		if (bill != null) {
			vo.setBillId(billId);
			vo.setBillName(bill.getName());
			vo.setBillEndTime(bill.getBillEndTime());
			List<SchoolPayItem> payItems = schoolPayItemMapper.selectByBillId(billId, schoolId);
			vo.setPayItems(payItems);
			List<ClassInfoVo> classInfoList = billClassMapMapper.selectByBillId(billId);
			if (CollectionUtils.isNotEmpty(classInfoList)) {
				List<Long> classIds = classInfoList.stream().map(ClassInfoVo::getId).collect(Collectors.toList());
				vo.setClassIds(classIds);
			}
		}
		return vo;
	}
}
